<!DOCTYPE html>
<html>
<head>
</head>
<body>

<script>
canvas = document.body.appendChild(document.createElement("canvas"))
canvas.height = 800
canvas.width = 800

const ctx = document.querySelector("canvas").getContext("2d");

vadd = ([x,y], [w,z]) => [x+w, y+z];
vrethtoxy = ([r, th]) => [r*cos(th), r*sin(th)];
vscale = (l, [x,y]) => [l*x, l*y];

const phi = (Math.sqrt(5)-1)/2;
const a36 = Math.PI/5;

cos = Math.cos;
sin = Math.sin;

let objects=[];
for (let i=0; i<5; i++) {
  objects.push({type:'K', size:0.5, summit:[0,0], angle:a36*2*i, side:1,  deco:[0.0, 1.0, 1.0]});
  objects.push({type:'K', size:0.5, summit:[0,0], angle:a36*2*i, side:-1, deco:[0.0, 1.0, 1.0]});
}

subdivide = (objects) => {
  let result = [];
  objects.forEach( (item) => {
    const d0 = item.deco[0];
    const d1 = item.deco[1];
    const d2 = item.deco[2];
    const d01 = phi * d0 + (1-phi) * d1;
    const d10 = phi * d1 + (1-phi) * d0;
    const d02 = phi * d0 + (1-phi) * d2;
    const d20 = phi * d2 + (1-phi) * d0;
    if (item.type === 'K') {
      const outervertex = vadd(item.summit, vrethtoxy([item.size, item.angle + item.side * a36]));
    	result.push({type:'D', size:item.size*phi, summit:item.summit, side:-item.side, angle:item.angle+a36*item.side, deco:[d0, d02, d10]});
      result.push({type:'K', size:item.size*phi, summit:outervertex, side:item.side, angle:item.angle-item.side*3*a36, deco:[d2,d10,d1]});
      result.push({type:'K', size:item.size*phi, summit:outervertex, side:-item.side, angle:item.angle-item.side*3*a36, deco:[d2,d10,d02]});
    }
    if (item.type === 'D') {
      const outervertex = vadd(item.summit, vrethtoxy([item.size, item.angle + item.side * a36]));
      result.push({type:'K', size:item.size*phi, summit:item.summit, side:item.side, angle:item.angle, deco:[d0,d1,d20]});
      result.push({type:'D', size:item.size*phi, summit:outervertex, side:item.side, angle:item.angle+item.side*6*a36, deco:[d2,d20,d1]});
    }
  });
  return result;
}

 
draw = (objects) => {
  w = Math.max(ctx.canvas.height, ctx.canvas.width);
  const tos = (p) => vscale(w, vadd([0.5,0.5], p));
  const alpha = 1.0;
  objects.forEach( (item) => {
    points = [tos(item.summit)];
    if (item.type === 'K') {
      ctx.fillStyle = `rgba(255, 165, ${255*item.deco[0]}, ${alpha})`;
      if (item.side < 0) {
        ctx.fillStyle = `rgba(205, 125, ${205*item.deco[0]}, ${alpha})`;
      }
      points.push(tos(vadd(item.summit, vrethtoxy([item.size, item.angle]))));
      points.push(tos(vadd(item.summit, vrethtoxy([item.size, item.angle + item.side * a36]))));
    }
    if (item.type === 'D') {
      ctx.fillStyle = `rgba(0, 255, 165, ${alpha})`;
      if (item.side < 0) {
        ctx.fillStyle = `rgba(0, 205, 125, ${alpha})`;
      }
      points.push(tos(vadd(item.summit, vrethtoxy([item.size * phi, item.angle]))));
      points.push(tos(vadd(item.summit, vrethtoxy([item.size, item.angle + item.side * a36]))));    
    }
    ctx.beginPath();
    ctx.moveTo(points[0][0], points[0][1]);
    ctx.lineTo(points[1][0], points[1][1]);
    ctx.lineTo(points[2][0], points[2][1]);    
    ctx.lineTo(points[0][0], points[0][1]);
    ctx.fill();
    ctx.stroke();
  });
}

const smax = 5;
for (let i=0; i<smax; i++) {
  objects = subdivide(objects);
}

draw(objects);

</script>
</body>
</html>
